using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Serilog;
using System.ComponentModel.DataAnnotations;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

/// <summary>
/// 统一的配置处理器 - 整合所有switch逻辑
/// 提供数据库类型、模板引擎、字段验证等统一处理方法
/// </summary>
public static class UnifiedConfigurationProcessor
{
    #region 数据库相关处理

    /// <summary>
    /// 数据库类型枚举
    /// </summary>
    public enum DatabaseType
    {
        SqlServer = 1,
        MySQL = 2,
        PostgreSQL = 3
    }

    /// <summary>
    /// 配置数据库上下文选项
    /// </summary>
    /// <param name="optionsBuilder">DbContext选项构建器</param>
    /// <param name="dbType">数据库类型</param>
    /// <param name="connectionString">连接字符串</param>
    public static void ConfigureDatabaseOptions(DbContextOptionsBuilder optionsBuilder, string dbType, string connectionString)
    {
        var normalizedType = NormalizeDatabaseType(dbType);
        
        switch (normalizedType)
        {
            case DatabaseType.SqlServer:
                optionsBuilder.UseSqlServer(connectionString);
                break;
            case DatabaseType.MySQL:
                optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
                break;
            case DatabaseType.PostgreSQL:
                optionsBuilder.UseNpgsql(connectionString);
                break;
            default:
                throw new NotSupportedException($"不支持的数据库类型: {normalizedType}。仅支持 PostgreSQL、SQL Server、MySQL。");
        }
    }

    /// <summary>
    /// 配置Serilog数据库日志记录
    /// </summary>
    /// <param name="loggerConfig">Serilog配置</param>
    /// <param name="dbType">数据库类型</param>
    /// <param name="connectionString">连接字符串</param>
    /// <param name="logger">可选的日志记录器</param>
    public static void ConfigureSerilogDatabase(LoggerConfiguration loggerConfig, string dbType, string connectionString, Microsoft.Extensions.Logging.ILogger? logger = null)
    {
        var normalizedType = NormalizeDatabaseType(dbType);
        
        switch (normalizedType)
        {
            case DatabaseType.PostgreSQL:
                if (!string.IsNullOrEmpty(connectionString))
                {
                    // 注意：需要安装 Serilog.Sinks.PostgreSQL NuGet包
                    logger?.LogInformation("🗄️ 配置PostgreSQL进行日志记录: {ConnectionString}", MaskConnectionString(connectionString));
                    // loggerConfig.WriteTo.PostgreSQL(connectionString, "Logs");
                }
                break;
                
            case DatabaseType.SqlServer:
                if (!string.IsNullOrEmpty(connectionString))
                {
                    // 注意：需要安装 Serilog.Sinks.MSSqlServer NuGet包
                    logger?.LogInformation("🗄️ 配置SqlServer进行日志记录: {ConnectionString}", MaskConnectionString(connectionString));
                    // loggerConfig.WriteTo.MSSqlServer(connectionString, "Logs");
                }
                break;
                
            case DatabaseType.MySQL:
                if (!string.IsNullOrEmpty(connectionString))
                {
                    // 注意：需要安装 Serilog.Sinks.MySQL NuGet包
                    logger?.LogInformation("🗄️ 配置MySQL进行日志记录: {ConnectionString}", MaskConnectionString(connectionString));
                    // loggerConfig.WriteTo.MySQL(connectionString);
                }
                break;
                
            default:
                logger?.LogWarning("⚠️ 不支持的数据库类型用于日志记录: {DbType}", normalizedType);
                break;
        }
    }

    /// <summary>
    /// 标准化数据库类型名称
    /// </summary>
    /// <param name="dbType">数据库类型字符串</param>
    /// <returns>标准化的数据库类型枚举</returns>
    public static DatabaseType NormalizeDatabaseType(string dbType)
    {
        if (string.IsNullOrEmpty(dbType))
            throw new ArgumentException("数据库类型不能为空", nameof(dbType));

        return dbType.ToLowerInvariant() switch
        {
            "sqlserver" or "mssql" or "sql server" => DatabaseType.SqlServer,
            "mysql" or "mariadb" => DatabaseType.MySQL,
            "postgres" or "postgresql" or "npgsql" => DatabaseType.PostgreSQL,
            _ => throw new NotSupportedException($"不支持的数据库类型: {dbType}。仅支持 PostgreSQL、SQL Server、MySQL。")
        };
    }

    /// <summary>
    /// 获取数据库类型的显示名称
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <returns>显示名称</returns>
    public static string GetDatabaseDisplayName(DatabaseType dbType)
    {
        return dbType switch
        {
            DatabaseType.SqlServer => "SQL Server",
            DatabaseType.MySQL => "MySQL",
            DatabaseType.PostgreSQL => "PostgreSQL",
            _ => "Unknown"
        };
    }

    /// <summary>
    /// 获取数据库连接字符串的键名
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <returns>连接字符串键名</returns>
    public static string GetConnectionStringKey(DatabaseType dbType)
    {
        return dbType switch
        {
            DatabaseType.SqlServer => "SqlServer",
            DatabaseType.MySQL => "MySql",
            DatabaseType.PostgreSQL => "Postgres",
            _ => throw new NotSupportedException($"不支持的数据库类型: {dbType}")
        };
    }

    #endregion

    #region 模板引擎相关处理

    /// <summary>
    /// 模板引擎类型枚举
    /// </summary>
    public enum TemplateEngine
    {
        Razor = 0,
        Liquid = 1,
        Handlebars = 2,
        Mustache = 3
    }

    /// <summary>
    /// 标准化模板引擎类型
    /// </summary>
    /// <param name="engine">引擎名称</param>
    /// <returns>标准化的引擎类型</returns>
    public static TemplateEngine NormalizeTemplateEngine(string engine)
    {
        if (string.IsNullOrEmpty(engine))
            return TemplateEngine.Razor;

        return engine.ToLowerInvariant() switch
        {
            "razor" or "cshtml" => TemplateEngine.Razor,
            "liquid" => TemplateEngine.Liquid,
            "handlebars" or "hbs" => TemplateEngine.Handlebars,
            "mustache" => TemplateEngine.Mustache,
            _ => TemplateEngine.Razor
        };
    }

    /// <summary>
    /// 获取模板引擎显示名称
    /// </summary>
    /// <param name="engine">模板引擎类型</param>
    /// <returns>显示名称</returns>
    public static string GetTemplateEngineDisplayName(TemplateEngine engine)
    {
        return engine switch
        {
            TemplateEngine.Razor => "Razor",
            TemplateEngine.Liquid => "Liquid",
            TemplateEngine.Handlebars => "Handlebars",
            TemplateEngine.Mustache => "Mustache",
            _ => "Unknown"
        };
    }

    /// <summary>
    /// 获取模板引擎文件扩展名
    /// </summary>
    /// <param name="engine">模板引擎类型</param>
    /// <returns>文件扩展名</returns>
    public static string GetTemplateEngineFileExtension(TemplateEngine engine)
    {
        return engine switch
        {
            TemplateEngine.Razor => ".cshtml",
            TemplateEngine.Liquid => ".liquid",
            TemplateEngine.Handlebars => ".hbs",
            TemplateEngine.Mustache => ".mustache",
            _ => ".html"
        };
    }

    #endregion

    #region 字段验证相关处理

    /// <summary>
    /// 字段类型枚举
    /// </summary>
    public enum FieldType
    {
        Text = 0,
        Number = 1,
        Integer = 2,
        Decimal = 3,
        Email = 4,
        Url = 5,
        Date = 6,
        DateTime = 7,
        Boolean = 8,
        Json = 9,
        Password = 10,
        TextArea = 11
    }

    /// <summary>
    /// 验证字段值格式
    /// </summary>
    /// <param name="fieldType">字段类型</param>
    /// <param name="value">字段值</param>
    /// <returns>验证结果</returns>
    public static (bool IsValid, string ErrorMessage) ValidateFieldValue(string fieldType, string value)
    {
        if (string.IsNullOrEmpty(value))
            return (true, string.Empty); // 空值通过验证，必填验证由其他地方处理

        var normalizedType = NormalizeFieldType(fieldType);
        
        return normalizedType switch
        {
            FieldType.Number or FieldType.Decimal => ValidateDecimal(value),
            FieldType.Integer => ValidateInteger(value),
            FieldType.Email => ValidateEmail(value),
            FieldType.Url => ValidateUrl(value),
            FieldType.Date or FieldType.DateTime => ValidateDate(value),
            FieldType.Boolean => ValidateBoolean(value),
            FieldType.Json => ValidateJson(value),
            _ => (true, string.Empty) // 其他类型暂不验证
        };
    }

    /// <summary>
    /// 标准化字段类型
    /// </summary>
    /// <param name="fieldType">字段类型字符串</param>
    /// <returns>标准化的字段类型枚举</returns>
    public static FieldType NormalizeFieldType(string fieldType)
    {
        if (string.IsNullOrEmpty(fieldType))
            return FieldType.Text;

        return fieldType.ToLowerInvariant() switch
        {
            "number" or "decimal" or "double" or "float" => FieldType.Decimal,
            "integer" or "int" or "long" => FieldType.Integer,
            "email" or "mail" => FieldType.Email,
            "url" or "uri" or "link" => FieldType.Url,
            "date" => FieldType.Date,
            "datetime" or "timestamp" => FieldType.DateTime,
            "boolean" or "bool" or "checkbox" => FieldType.Boolean,
            "json" or "object" => FieldType.Json,
            "password" or "pwd" => FieldType.Password,
            "textarea" or "text-area" or "multiline" => FieldType.TextArea,
            _ => FieldType.Text
        };
    }

    #endregion

    #region 私有辅助方法

    /// <summary>
    /// 掩码连接字符串中的敏感信息
    /// </summary>
    private static string MaskConnectionString(string connectionString)
    {
        if (string.IsNullOrEmpty(connectionString))
            return string.Empty;

        // 简单的掩码处理，实际项目中可以更复杂
        var parts = connectionString.Split(';');
        var maskedParts = new List<string>();

        foreach (var part in parts)
        {
            if (part.Contains("Password", StringComparison.OrdinalIgnoreCase) ||
                part.Contains("Pwd", StringComparison.OrdinalIgnoreCase))
            {
                var keyValue = part.Split('=');
                if (keyValue.Length == 2)
                    maskedParts.Add($"{keyValue[0]}=****");
                else
                    maskedParts.Add(part);
            }
            else
            {
                maskedParts.Add(part);
            }
        }

        return string.Join(";", maskedParts);
    }

    /// <summary>
    /// 验证小数格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateDecimal(string value)
    {
        if (double.TryParse(value, out _))
            return (true, string.Empty);
        return (false, "不是有效的数字格式");
    }

    /// <summary>
    /// 验证整数格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateInteger(string value)
    {
        if (int.TryParse(value, out _))
            return (true, string.Empty);
        return (false, "不是有效的整数格式");
    }

    /// <summary>
    /// 验证邮箱格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateEmail(string value)
    {
        try
        {
            var addr = new System.Net.Mail.MailAddress(value);
            if (addr.Address == value)
                return (true, string.Empty);
        }
        catch
        {
            // 忽略异常
        }
        return (false, "不是有效的邮箱格式");
    }

    /// <summary>
    /// 验证URL格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateUrl(string value)
    {
        if (Uri.TryCreate(value, UriKind.Absolute, out _))
            return (true, string.Empty);
        return (false, "不是有效的URL格式");
    }

    /// <summary>
    /// 验证日期格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateDate(string value)
    {
        if (DateTime.TryParse(value, out _))
            return (true, string.Empty);
        return (false, "不是有效的日期格式");
    }

    /// <summary>
    /// 验证布尔值格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateBoolean(string value)
    {
        if (bool.TryParse(value, out _))
            return (true, string.Empty);
        return (false, "不是有效的布尔值格式");
    }

    /// <summary>
    /// 验证JSON格式
    /// </summary>
    private static (bool IsValid, string ErrorMessage) ValidateJson(string value)
    {
        try
        {
            System.Text.Json.JsonDocument.Parse(value);
            return (true, string.Empty);
        }
        catch (System.Text.Json.JsonException)
        {
            return (false, "不是有效的JSON格式");
        }
    }

    #endregion

    #region 统一配置访问方法

    /// <summary>
    /// 根据数据库类型获取连接字符串
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>连接字符串</returns>
    public static string GetDatabaseConnectionString(string dbType, string? defaultValue = null)
    {
        var normalizedType = NormalizeDatabaseType(dbType);
        var key = GetConnectionStringKey(normalizedType);
        var connectionString = ConfigurationAccessor.GetConnectionString(key);
        
        if (string.IsNullOrEmpty(connectionString))
        {
            connectionString = defaultValue ?? GetDefaultConnectionString(normalizedType);
        }
        
        return connectionString;
    }

    /// <summary>
    /// 获取默认连接字符串
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <returns>默认连接字符串</returns>
    private static string GetDefaultConnectionString(DatabaseType dbType)
    {
        return dbType switch
        {
            DatabaseType.SqlServer => "Server=(localdb)\\mssqllocaldb;Database=LowCodePlatform;Trusted_Connection=true;MultipleActiveResultSets=true",
            DatabaseType.MySQL => "Server=localhost;Database=lowcode;Uid=root;Pwd=123456;",
            DatabaseType.PostgreSQL => "Host=localhost;Database=lowcode;Username=postgres;Password=123456",
            _ => throw new NotSupportedException($"不支持的数据库类型: {dbType}")
        };
    }

    #endregion
}
